#include "OpenGLDevice.h"

using namespace Pantsu;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
	
	switch (message)
	{
		
	case WM_CREATE:
		return 0;
		
	case WM_CLOSE:
		PostQuitMessage( 0 );
		return 0;
		
	case WM_DESTROY:
		return 0;
		
	case WM_KEYDOWN:
		switch ( wParam )
		{
			
		case VK_ESCAPE:
			PostQuitMessage(0);
			return 0;
			
		}
		return 0;
	
	default:
		return DefWindowProc( hWnd, message, wParam, lParam );
			
	}
}

OpenGLDevice::OpenGLDevice(  HINSTANCE i_instance ) {
	m_hInstance = i_instance;
}

OpenGLDevice::~OpenGLDevice() {

}

void OpenGLDevice::RenderOneFrame() {
	
	
	// check for messages
	if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )  ) {
		
		// handle or dispatch messages
		if ( msg.message == WM_QUIT ) {
			//quit = TRUE;
		} 
		else {
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		
	} 
	else {
		
		m_pSceneManager->Update();
		SwapBuffers( hDC );
	}
	
}

HRESULT OpenGLDevice::Init( int i_iWidth, int i_iHeight ) {

	/*WNDCLASS wc;
	HWND hWnd;
	HDC hDC;
	HGLRC hRC;
	MSG msg;*/
	
	
	// register window class
	wc.style = CS_OWNDC;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = m_hInstance;
	wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
	wc.hCursor = LoadCursor( NULL, IDC_ARROW );
	wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
	wc.lpszMenuName = NULL;
	wc.lpszClassName = "GLSample";
	RegisterClass( &wc );
	
	// create main window
	hWnd = CreateWindow( 
		"GLSample", "Pantsu Engine", 
		WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
		0, 0, i_iWidth, i_iHeight,
		NULL, NULL, m_hInstance, NULL );
	
	// enable OpenGL for the window
	EnableOpenGL( hWnd, &hDC, &hRC );
	
	// shutdown OpenGL
	//DisableOpenGL( hWnd, hDC, hRC );
	
	// destroy the window explicitly
	//DestroyWindow( hWnd );
	
	return msg.wParam;
}

void OpenGLDevice::DeInit() {

	// shutdown OpenGL
	DisableOpenGL( hWnd, hDC, hRC );
	
	// destroy the window explicitly
	DestroyWindow( hWnd );
}

HRESULT OpenGLDevice::EnableOpenGL( HWND hWnd, HDC *hDC, HGLRC *hRC ) {

	PIXELFORMATDESCRIPTOR pfd;
	int format;
	
	// get the device context (DC)
	*hDC = GetDC( hWnd );
	
	// set the pixel format for the DC
	ZeroMemory( &pfd, sizeof( pfd ) );
	pfd.nSize = sizeof( pfd );
	pfd.nVersion = 1;
	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = 24;
	pfd.cDepthBits = 16;
	pfd.iLayerType = PFD_MAIN_PLANE;
	format = ChoosePixelFormat( *hDC, &pfd );
	SetPixelFormat( *hDC, format, &pfd );
	
	// create and enable the render context (RC)
	*hRC = wglCreateContext( *hDC );
	wglMakeCurrent( *hDC, *hRC );
	return S_OK;
}

void OpenGLDevice::DisableOpenGL( HWND hWnd, HDC hDC, HGLRC hRC ) {

	wglMakeCurrent( NULL, NULL );
	wglDeleteContext( hRC );
	ReleaseDC( hWnd, hDC );
}

HRESULT OpenGLDevice::BeginRendering(bool, bool, bool) {

	return S_OK;
}

void OpenGLDevice::EndRendering() {
}

void OpenGLDevice::Release() {
}

HRESULT OpenGLDevice::UseWindow( UINT i_nHwnd ) {
	return S_OK;
}

HRESULT OpenGLDevice::Clear( bool, bool, bool ) {

	return S_OK;
}

